package com.duqc.quartz.scheduled;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * @ClassName ConfigurerSchedulingDemo
 * @Description 定时任务的任务名称，cron（定时任务表达式），定时任务开关，存储在数据库表中。在不重启项目的情况下，修改定时任务表达式，可以实时获取新的定时任务执行时间规则；修改定时任务执行状态，可以随时开关定时任务。
 * @Author duqc
 * @Date 2021/11/19
 **/
@Configuration
@EnableScheduling
public abstract class ConfigurerSchedulingDemo implements SchedulingConfigurer {

    /**
     * 定时任务周期表达式
     */
    private String cron;

    /**
     * 重写配置定时任务方法
     *
     * @param taskRegistrar
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskScheduler());
        taskRegistrar.addTriggerTask(
                //执行定时任务
                this::taskService,
                //设置触发器
                triggerContext -> {
                    //获取定时任务周期表达式
                    cron = getCron();
                    CronTrigger trigger = new CronTrigger(cron);
                    return trigger.nextExecutionTime(triggerContext);
                }
        );
    }

    /**
     * 获取定时任务周期表达式
     *
     * @return
     */
    public abstract String getCron();

    /**
     * 执行定时任务
     */
    public abstract void taskService();

    @Bean
    private Executor taskScheduler() {
        //设置线程名称
        ThreadFactory build = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
        //创建线程池
        return Executors.newScheduledThreadPool(5, build);
    }
}
